package edu.study.common.util.ftp;

import com.jcraft.jsch.*;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.Vector;

@Deprecated
@Slf4j
public class SFTPClient {

    private ChannelSftp channelSftp;

    private SFTPClient() {

    }

    public static SFTPClient createPwdAuthClientInstance(ScpBean bean) throws JSchException {
        return createPwdAuthClientInstance(bean, null);
    }

    public static SFTPClient createPwdAuthClientInstance(ScpBean bean, Proxy proxy) throws JSchException {
        log.info("SFTPClient.createPwdAuthClientInstance(); 开始 bean={}, proxy={}", bean, proxy);
        SFTPClient client = new SFTPClient();
        JSch jsch = new JSch();
        Session session = null;
        Channel channel = null;

        session = jsch.getSession(bean.getUsername(), bean.getRemoteAddress(), bean.getRemotePort());
        session.setPassword(bean.getPassword());
        session.setTimeout(10000);
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);

        session.setProxy(proxy);

        session.connect();

        channel = session.openChannel("sftp");
        channel.connect();
        client.channelSftp = (ChannelSftp) channel;
        log.info("SFTPClient.createPwdAuthClientInstance(); 结束");
        return client;
    }

    public static SFTPClient createRsaAuthClientInstance(ScpBean bean, String prvkey) throws JSchException {
        log.info("SFTPClient.createRsaAuthClientInstance(); 开始 bean={}, prvkey={}", bean, prvkey);
        SFTPClient client = new SFTPClient();
        JSch jsch = new JSch();
        Session session = null;
        Channel channel = null;
        jsch.addIdentity(bean.getUsername(), prvkey.getBytes(), null, null);
        session = jsch.getSession(bean.getUsername(), bean.getRemoteAddress(), bean.getRemotePort());
        session.setTimeout(10000);
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();

        channel = session.openChannel("sftp");
        channel.connect();
        client.channelSftp = (ChannelSftp) channel;
        log.info("SFTPClient.createRsaAuthClientInstance(); 结束 bean={}, prvkey={}", bean, prvkey);
        return client;
    }

    public static SFTPClient createRsaFileAuthClientInstance(ScpBean bean, String prvkey) throws JSchException {
        return createRsaFileAuthClientInstance(bean, prvkey, null);
    }

    public static SFTPClient createRsaFileAuthClientInstance(ScpBean bean, String prvkey, Proxy proxy) throws JSchException {
        log.info("SFTPClient.createRsaFileAuthClientInstance(); 开始 bean={}, prvkey={}, proxy={}", bean, prvkey, proxy);
        SFTPClient client = new SFTPClient();
        JSch jsch = new JSch();
        Session session = null;
        Channel channel = null;
        jsch.addIdentity(prvkey);
        session = jsch.getSession(bean.getUsername(), bean.getRemoteAddress(), bean.getRemotePort());
        session.setTimeout(10000);
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);

        session.setProxy(proxy);

        session.connect();

        channel = session.openChannel("sftp");
        channel.connect();
        client.channelSftp = (ChannelSftp) channel;
        log.info("SFTPClient.createRsaFileAuthClientInstance(); 结束");
        return client;
    }

    public void close() {
        if (channelSftp != null) {
            channelSftp.quit();
            try {
                Session session = channelSftp.getSession();
                session.disconnect();
            } catch (JSchException e) {
                log.error("SFTClient.close(); 发生异常", e);
            }
        }

    }

    public boolean isFileExist(String path) {
        try {
            @SuppressWarnings("unchecked")
            Vector<LsEntry> v = channelSftp.ls(path);
            if (v.size() == 1) {
                return true;
            } else {
                return false;
            }
        } catch (SftpException e) {
            log.error("{} 文件不存在: ", path, e);
            return false;
        }

    }

    public void makeDirs(String path) throws SftpException {
        String[] folders = path.split("/");
        String returnPath = "";
        for (String folder : folders) {
            if (folder.length() > 0) {
                try {
                    log.info("====>try open dir:" + folder);
                    channelSftp.cd(folder);
                } catch (SftpException e) {
                    log.info("====>try create dir:" + folder);
                    channelSftp.mkdir(folder);
                    channelSftp.cd(folder);
                }
            }
            returnPath = returnPath + "../";
        }
        channelSftp.cd(returnPath);
    }

    public void download(String ftpFilePathFrom, String localPathTo) throws SftpException {
        log.info("SFTPClient.download(); 开始 {} ---> {}", ftpFilePathFrom, localPathTo);
        @SuppressWarnings("unchecked")
        Vector<LsEntry> v = channelSftp.ls(ftpFilePathFrom);
        if (v.size() == 1) {
            LsEntry entry = v.get(0);
            SftpATTRS attrs = entry.getAttrs();
            File locaclPath = new File(localPathTo);
            if (!locaclPath.exists()) {
                locaclPath.mkdirs();
            }
            if (!attrs.isDir() && !attrs.isLink()) {
                channelSftp.get(ftpFilePathFrom, localPathTo);
            }
        }
        log.info("SFTPClient.download(); 结束 {} ---> {}", ftpFilePathFrom, localPathTo);
    }

    public void uploadFile(String srcFile, String dstFile) throws Exception {
        log.info("SFTPClient.uploadFile(); 开始 {} ---> {}", srcFile, dstFile);
        OutputStream out = null;
        InputStream is = null;
        try {
            log.info("upload files begin.");
            out = channelSftp.put(dstFile, ChannelSftp.OVERWRITE); // 使用OVERWRITE模式
            byte[] buff = new byte[1024 * 256]; // 设定每次传输的数据块大小为256KB
            int read;
            if (out != null) {
                System.out.println("Start to read input stream");
                is = new FileInputStream(srcFile);
                do {
                    read = is.read(buff, 0, buff.length);
                    if (read > 0) {
                        out.write(buff, 0, read);
                    }
                    out.flush();
                } while (read >= 0);
                System.out.println("input stream read done.");
            }
            log.info("upload files end.");
        } catch (Exception e) {
            log.info("upload files exception. srcFile:" + srcFile, e);
            throw e;
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (Exception e) {
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                }
            }
        }
        log.info("SFTPClient.uploadFile(); 结束 {} ---> {}", srcFile, dstFile);
    }

}
